09. Private and Public

What do Private, Protected and Public Mean?

In the Gaussian class declaration, the mu and sigma2 variables were marked as private whereas the rest of the variables and functions were in a section marked public. Here is a reminder of the class declaration:

class Gaussian
{
    private:
        float mu, sigma2;

    public:

        // constructor functions
        Gaussian ();
        Gaussian (float, float);

        // change value of average and standard deviation 
        void setMu(float);
        void setSigma2(float);

        // output value of average and standard deviation
        float getMu();
        float getSigma2();

        // functions to evaluate 
        float evaluate (float);
        Gaussian multiply (Gaussian);
        Gaussian add (Gaussian);
};

Private and Public

These keywords private and public determine which part of your program will have access to the variables and functions. If a variable or function is private, then only the class code itself has access to these variables and functions.

On the other hand, anything marked public can be accessed outside the class; for example, when you instantiate an object, your program will be able to use the set and get functions as well as the evaluate, multiply and add functions; however, your program will not be able to access the mu and sigma2 variables directly.

Protected

There is another keyword called protected, which wasn't used in the example. Basically, protected classes and variables can be accessed by any subclasses. For example, if you wrote a Vehicle class, you might write a Car class, a Van class, and a Truck class that would all inherit from the more general Vehicle class. Any protected variables in the Vehicle class could be accessed in the child classes.

Example of Public vs. Private

Below is another example of the Gaussian class except mu and sigma2 have been made public. Notice how it is no longer necessary to have getMu, getSigma2, setMu and setSigma2 functions because the object has direct access to those variables.

Start Quiz:

#include <iostream>
#include "gaussian.h"

int main ()
{

	Gaussian mygaussian(30.0,20.0);
	Gaussian othergaussian(10.0,30.0);
	
	std::cout << "average " << mygaussian.mu << std::endl;
	
	std::cout << "evaluation " << mygaussian.evaluate(15.0) << std::endl;

	std::cout << "mul results sigma " << mygaussian.mul(othergaussian).sigma2 << std::endl;
	std::cout << "mul results average " << mygaussian.mul(othergaussian).mu << std::endl;

	std::cout << "add results sigma " << mygaussian.add(othergaussian).sigma2 << std::endl;
	std::cout << "add results average " << mygaussian.add(othergaussian).mu << std::endl;

	std::cout << "average " << mygaussian.mu << std::endl;
    mygaussian.mu = 25;
    std::cout << "average " << mygaussian.mu << std::endl;
     
	return 0;
}
#include <math.h>       /* sqrt, exp */
#include "gaussian.h"

Gaussian::Gaussian() {
	mu = 0;
	sigma2 = 1;	
}

Gaussian::Gaussian (float average, float sigma) {
	mu = average;
	sigma2 = sigma;
}

float Gaussian::evaluate(float x) {
	float coefficient;
	float exponential;

	coefficient = 1.0 / sqrt (2.0 * M_PI * sigma2);
	exponential = exp ( pow (-0.5 * (x - mu), 2) / sigma2 );
	return coefficient * exponential;
}

Gaussian Gaussian::mul(Gaussian other) {
	float denominator;
	float numerator;
	float new_mu;
	float new_var;

	denominator = sigma2 + other.sigma2;
	numerator = mu * other.sigma2 + other.mu * sigma2;
	new_mu = numerator / denominator;

	new_var = 1.0 / ( (1.0 / sigma2) + (1.0 / other.sigma2) );

	return Gaussian(new_mu, new_var);
}

Gaussian Gaussian::add(Gaussian other) {

	float new_mu;
	float new_sigma2;

	new_mu = mu + other.mu;
	new_sigma2 = sigma2 + other.sigma2;

	return Gaussian(new_mu, new_sigma2);
}
class Gaussian
{

	public:

		float mu, sigma2;
		
		// constructor functions
		Gaussian ();
		Gaussian (float, float);

		// functions to evaluate 
		float evaluate (float);
		Gaussian mul (Gaussian);
		Gaussian add (Gaussian);
};

Why Keep Things Private

By default, C++ makes all class variables and functions private. That means you can actually declare private variables and functions at the top of your class declaration without even labeling them private:

class Gaussian
{
    float mu, sigma2;

    public:

        // constructor functions
        Gaussian ();
        Gaussian (float, float);

        // change value of average and standard deviation 
        void setMu(float);
        void setSigma2(float);

        // output value of average and standard deviation
        float getMu();
        float getSigma2();

        // functions to evaluate 
        float evaluate (float);
        Gaussian mul (Gaussian);
        Gaussian add (Gaussian);
};

C++ thus encourages you to make everything private unless you have a good reason not to do so. For example, by making the mu and sigma2 variables private, you have separated how mu and sigma2 are implemented versus how mu and sigma2 are accessed.

What happens if the way your class calculates mu and sigma2 changes? If these variables had been public, then any code that uses your class might break. When mu and sigma2 were public, a program could directly change the value of mu and sigma with code like:

    mygaussian.mu = 25;

But when mu and sigma2 were private, a program had to use code like this:

mygaussian.setMu(25)

If you needed to change something about the implementation of the mu variable, you would be much less likely to break existing code in the private case. A program using the Gaussian class does not need to know how mu was implemented as long as the program can get the mu value and change the value in mu.